package com.pdool.room.core;

import cn.hutool.core.util.ReflectUtil;
import com.google.protobuf.Parser;
import com.pdool.room.handler.IRoomHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class MsgMap implements BeanPostProcessor {

    Map<Integer, MsgHandlerItem> msgMap = new HashMap<>();

    public MsgHandlerItem getMsgMethod(int msgId) {
        return msgMap.get(msgId);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        try {
            Class<?> targetClass = AopUtils.getTargetClass(bean);
            MsgHandler annotation = targetClass.getAnnotation(MsgHandler.class);
            if (annotation != null) {
                IRoomHandler handlerBean = (IRoomHandler) bean;
                int msgId = annotation.value();
                Type[] genericSuperclass = targetClass.getGenericInterfaces();
                ParameterizedType type = (ParameterizedType) genericSuperclass[0];
                Type[] actualTypeArguments = type.getActualTypeArguments();
                Class in = (Class) actualTypeArguments[0];
                Method inParserMethod = ReflectUtil.getMethod(in, "parser");
                Parser inParser = (Parser) inParserMethod.invoke(null);
                msgMap.put(msgId, new MsgHandlerItem(msgId, inParser, handlerBean));
            }
        } catch (Exception e) {
            log.error("", e);
        }

        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }
}
